//-------------------------------------------------------------------
//	Copyright (c) 2010-2012 Zhirnov Andrey
//	This file is part of the "UXGEN" project.
//	See copyright notice in "Engine.h".
//-------------------------------------------------------------------

#ifndef _UX_BASE_MATERIAL_H
#define _UX_BASE_MATERIAL_H

#include "../CResource.h"
#include "../../Systems/Render/CRender.h"

namespace Engine
{
namespace Resources
{
	

	//
	// Material Texture
	//

	struct TMaterialTexture
	{
		CTexturePtr		pTexture;
		uint			uSamplerID;
		e_texture::type	eType;
		uint8			uStage;		// set while linking
		///
		TMaterialTexture():
			pTexture(nullptr), uStage(-1), uSamplerID(0), eType(e_texture::UNKNOWN) {}
		
		TMaterialTexture(const CTexturePtr &tex, e_texture::type type = e_texture::DIFFUSE):
			pTexture(tex), uStage(-1), eType(type), uSamplerID(0) {}

		TMaterialTexture(const CTexturePtr &tex, e_texture::type type, uint8 stage, uint samp = 0):
			pTexture(tex), eType(type), uStage(stage), uSamplerID(samp) {}
	};

	typedef array< TMaterialTexture >		texture_array_t;



	//
	// Program Shell Material
	//

	class IProgramMaterial : public IBaseMaterial
	{
	public:
		virtual bool  Link() = 0;
		virtual bool  SetProgram(const CBaseProgramShellPtr &pProgram) = 0;
		virtual void  GetTextures(texture_array_t *&pTextures, uint *&pActiveTextures) = 0;
		virtual void  GetProgram(CBaseProgramShellPtr &pProgram) = 0;
		virtual bool  SetMaterialData(const TProgramData &sData) = 0;
		virtual bool  GetMaterialData(TProgramData &sData) = 0;
		virtual uint8 GetMaterialLOD() const = 0;
	};



	//
	// Material interface
	//

	class _EXPORT_ IMaterial : public CResource, public IRTEventListener//, public IConfigResource
	{
	public:
		typedef pod_array< IProgramMaterial *>		progmtr_array_t;

		IMaterial(const char *pFileName): CResource(pFileName) {}

		virtual bool Link() = 0;
		virtual bool IsExist(e_render_layer::type eLayer, uint8 uLOD) = 0;
		virtual bool GetProgramMaterial(IProgramMaterial *&pMtr, e_render_layer::type eLayer, uint8 uLOD = 0) = 0;
		virtual void GetUniqueMaterials(progmtr_array_t &aMaterials) = 0;

		virtual e_render_layer::bits GetLayerBits() const = 0;
	};


	
	//
	// Material Init Params
	//

	struct TMaterialInit
	{
		struct TMaterialPassInit
		{
			texture_array_t				aTextures;
			binary_buffer_t				aData;
			TGLRenderState				sStates;
			e_material::type			eMtrType;
			e_program_data::type		eProgData;
			e_render_layer::type		eLayer;
			e_render_state_lock::type	eRSLock;
			uint8						uLOD;
			bool						bLock;
			///
			TMaterialPassInit():
				eMtrType(e_material::UNKNOWN),
				eProgData(e_program_data::UNKNOWN),
				eRSLock(e_render_state_lock::UNKNOWN),
				uLOD(0),
				bLock(false)
			{}
		};

		array< TMaterialPassInit >	aPasses;
		///
		TMaterialInit() {}
	};

//-------------------------------------------------------------------

}	// Resources
}	// Engine

#endif	// _UX_BASE_MATERIAL_H